package com.googlecode.hyakutaded;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.mortbay.util.ajax.Continuation;

import com.googlecode.hyakutaded.json.JSONException;
import com.googlecode.hyakutaded.json.JSONObject;

public class Client {
	private String id;
	private long packetId = 0L;
	private long lastAccess = 0l;
	private Packet currentPacket = new Packet(packetId);
	private Packet lastPacket = new Packet(-1);
	private Map<String, String> properties = new HashMap<String, String>();
	private transient Continuation cont = null;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public long getLastAccess() {
		return lastAccess;
	}

	public void setLastAccess(long lastAccess) {
		this.lastAccess = lastAccess;
	}

	public synchronized void add(String key, JSONObject o) throws JSONException {
		currentPacket.add(key, o);
		if (cont != null) {
			cont.resume();
		}
	}

	public synchronized void update(String key, String subkey, JSONObject value)
			throws JSONException {
		currentPacket.update(key, subkey, value);
	}

	public synchronized void set(String key, JSONObject o) throws JSONException {
		currentPacket.set(key, o);
		if (cont != null) {
			cont.resume();
		}
	}

	public void setProperty(String key, String value) {
		this.properties.put(key, value);
	}

	public Map<String, String> getProperties() {
		return Collections.unmodifiableMap(properties);

	}

	public synchronized Packet getPacket(long packetId, Continuation cont,
			long timeout) {
		this.cont = cont;
		if (packetId == currentPacket.getId()) {
			if (currentPacket.getEdits() > 0) {
				lastPacket = currentPacket;
				packetId++;
				currentPacket = new Packet(packetId);
				lastAccess = System.currentTimeMillis();
				return lastPacket;
			} else {
				cont.suspend(timeout);
				lastPacket = currentPacket;
				packetId++;
				currentPacket = new Packet(packetId);
				lastAccess = System.currentTimeMillis();
				return lastPacket;
			}
		}
		return lastPacket;
	}
}
